﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ZedGraph;
using System.Drawing;
using Statistics;
namespace GeostatisticalTool.Classes
{
    public class SemivarianceCovarianceGraph
    {
        private ZedGraphControl zedGraphControl1;
        private ISpatialContinuityData spatial;



        public ISpatialContinuityData Spatial
        {
            get { return spatial; }
            set { spatial = value; 
                  
            }
        }

        public SemivarianceCovarianceGraph(ZedGraphControl zed,ISpatialContinuityData spatial)
        {
            this.zedGraphControl1 = zed;
            this.spatial = spatial;
            if (spatial!= null)
            {
            
            }
           
        }




        public void DrawCurve(string name,double[] x, double[] y, Color c)
        {
            CurveItem theo = zedGraphControl1.GraphPane.CurveList[name];
            if (theo != null)
             zedGraphControl1.GraphPane.CurveList.Remove(theo);

            ZedGraph.LineItem myCurve = zedGraphControl1.GraphPane.AddCurve(name,x, y, c);
            myCurve.Line.Width = 1f;
            myCurve.Symbol.Type = ZedGraph.SymbolType.None;
            //myCurve.Line.Fill.Color = Color.LightBlue;
            //myCurve.Line.Fill.Color = Color.FromArgb(100, 0, 0, 255);
          //  myCurve.Line.Fill.IsVisible = true;
            zedGraphControl1.Refresh();
        }


        public void DrawCurve(IKrigingModel method)
        {
            double maxDist = spatial.GetDistancesValues().Max()/ 150;
            double[] dist = new double[150];
            double[] sem = new double[150];

            for (int i = 0; i < 150; i++) {
                dist[i] = i * maxDist;
                sem[i] = method.GetValue(dist[i]);
            }
            DrawCurve("Model", dist, sem, Color.Red);


        }


        public void DrawCurve(IKrigingModel method, string name, Color color)
        {
            double maxDist = spatial.GetDistanceStatistic().Max / 150;
            double[] dist = new double[150];
            double[] sem = new double[150];

            for (int i = 0; i < 150; i++)
            {
                dist[i] = i * maxDist;
                sem[i] = method.GetValue(dist[i]);
            }
            DrawCurve(name , dist, sem, color);


        }



        public void Graph()
        {

            zedGraphControl1.GraphPane.CurveList.Clear();
          //  ZedGraph.LineItem myCurve = zedGraphControl1.GraphPane.AddCurve("Elevation Profile", distanceArray, elevationArray, Color.Blue);
          //  myCurve.Line.Width = 2f;
          //  myCurve.Symbol.Type = ZedGraph.SymbolType.None;
            //myCurve.Line.Fill.Color = Color.LightBlue;
            //myCurve.Line.Fill.Color = Color.FromArgb(100, 0, 0, 255);
            //myCurve.Line.Fill.IsVisible = true;
            ZedGraph.LineItem myPoint = zedGraphControl1.GraphPane.AddCurve("Semivariances", spatial.GetDistancesValues(), spatial.GetSemivariancesValues(), Color.Red);
            myPoint.Symbol.Type = ZedGraph.SymbolType.Circle;
            myPoint.Line.IsVisible=false;


            zedGraphControl1.GraphPane.XAxis.Title.Text = "Distance (h) ";
            zedGraphControl1.GraphPane.YAxis.Title.Text = "Semivariance ";

            //refresh the graph
            zedGraphControl1.AxisChange();

            //set the graph title
            zedGraphControl1.GraphPane.Title.Text = "Semivariance";
            zedGraphControl1.Refresh();
           // test(spatial.SemivarianceStatistic.Mean, spatial.DistanceStatistic.Mean);
        }

        public void GraphWithoutClear(string name,Color color)
        {

          //  zedGraphControl1.GraphPane.CurveList.Clear();
            //  ZedGraph.LineItem myCurve = zedGraphControl1.GraphPane.AddCurve("Elevation Profile", distanceArray, elevationArray, Color.Blue);
            //  myCurve.Line.Width = 2f;
            //  myCurve.Symbol.Type = ZedGraph.SymbolType.None;
            //myCurve.Line.Fill.Color = Color.LightBlue;
            //myCurve.Line.Fill.Color = Color.FromArgb(100, 0, 0, 255);
            //myCurve.Line.Fill.IsVisible = true;
            ZedGraph.LineItem myPoint = zedGraphControl1.GraphPane.AddCurve(name, spatial.GetDistancesValues(), spatial.GetSemivariancesValues(), color);
            myPoint.Symbol.Type = ZedGraph.SymbolType.Circle;
            myPoint.Symbol.Fill.Color = color;
            myPoint.Line.IsVisible = false;


            zedGraphControl1.GraphPane.XAxis.Title.Text = "Distance (h) ";
            zedGraphControl1.GraphPane.YAxis.Title.Text = "Semivariance ";

            //refresh the graph
            zedGraphControl1.AxisChange();

            //set the graph title
            zedGraphControl1.GraphPane.Title.Text = "Semivariance";
            zedGraphControl1.Refresh();
            // test(spatial.SemivarianceStatistic.Mean, spatial.DistanceStatistic.Mean);
        }



        private void test(double initialSill, double initialRange)
        {

          //  double[] temperature = new double[] { 229.15, 247.85, 256.95, 267.15, 278.15, 285.25, 294.35, 307.95, 323.05, 337.85 };
          //  double[] pressure = new double[] { 133.3224898, 666.6124489, 1333.224898, 2666.449795, 5332.899591, 7999.349386, 13332.24898, 26664.49795, 53328.99591, 101325.0922 };

            double[,] z = new double[2, spatial.GetDistancesValues().Length];

            for (int i = 0; i < spatial.GetDistancesValues().Length; i++)
            {
                z[0, i] = spatial.GetDistancesValues()[i];
                z[1, i] = spatial.GetSemivariancesValues()[i];
            }

            Parameter S = new Parameter(initialSill);
            Parameter R = new Parameter(initialRange);
            Parameter D = new Parameter(0.0);

            Func<double> regressionFunction = () => S * (1 - Math.Exp((-3* Math.Abs(D))/R));
            Parameter[] regressionParameters = new Parameter[] {R, S};
            Parameter[] observedParameters = new Parameter[] { D };
            LevenbergMarquardt levenbergMarquardt = new LevenbergMarquardt(regressionFunction, regressionParameters, observedParameters, z);

            for (int i = 0; i < 50; i++)
            {
                levenbergMarquardt.Iterate();
            }

        
        }

        
    }
}
